package com.bangcommunity.bbframe.dynconfig.dynlog;

import com.bangcommunity.bbframe.common.utils.io.PropertiesUtil;
import com.bangcommunity.bbframe.common.utils.lang.StringUtils;
import com.bangcommunity.bbframe.dynconfig.DynConfigRegister;
import com.bangcommunity.bbframe.dynconfig.IDynConfigProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 *
 * @author tanghc
 * @date 17/2/27
 */
public class LogLevelMonitor {
    private static Logger logger = LoggerFactory.getLogger(LogLevelMonitor.class);
    private static final String log_groupid = "common";
    private static final String log_dataid = "loglevel";
    private static final Map<String, LogLevelConfig> logLevelConfigMap = new HashMap<>();

    enum BindLoger {
        logback, log4j
    }

    static {
        logLevelConfigMap.put(BindLoger.logback.name(),
                new LogLevelConfig("ch.qos.logback.classic.Logger", "ch.qos.logback.classic.Level"));
        logLevelConfigMap.put(BindLoger.log4j.name(),
                new LogLevelConfig("org.apache.log4j.Logger", "org.apache.log4j.Level"));
        DynConfigRegister.getInstance().buildOnce(log_groupid, log_dataid, new IDynConfigProcessor() {
            @Override
            public void procesConfig(String config) {
                Properties properties = PropertiesUtil.loadFromString(config);
                changeLogLevel(properties);
            }
        });
    }

    public static void startMonitor() {
        logger.info("init LogLevelMonitor");
    }

    public static void changeLogLevel(Properties properties) {
        if (null != properties) {
            Map<String, String> loggerMap = new HashMap<>();
            String bindLoggerNames = "";
            if (null != properties) {
                for (Map.Entry<Object, Object> entry : properties.entrySet()) {
                    if (null == entry || null == entry.getKey() || null == entry.getValue()) {
                        logger.info("invalid loglev config: {}", entry);
                        continue;
                    }
                    String key = entry.getKey().toString();
                    String value = entry.getValue().toString();
                    if (key.equals("bind")) {
                        bindLoggerNames = value;
                        continue;
                    }
                    loggerMap.put(key, value);

                    // Level level = Level.toLevel(value);
                    // if(null == level){
                    // logger.info("invalid loglev config of level: entry={}",entry);
                    // continue;
                    // }
                    // ch.qos.logback.classic.Logger log =
                    // (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(key);
                    // if(log.getLevel() != null) {
                    // if(log.getLevel().toInt() != level.toInt()){
                    // log.setLevel(level);
                    // }else{
                    //
                    // }
                    // }else{
                    // log.setLevel(level);
                    // }

                }
            }
            if (StringUtils.isBlank(bindLoggerNames)) {

            } else {
                String[] binds = bindLoggerNames.split(",");
                for (Map.Entry<String, String> entry : loggerMap.entrySet()) {
                    if (null != binds) {
                        for (String bind : binds) {
                            changeLogger(bind, entry.getKey(), entry.getValue());
                        }
                    }
                }
            }
        }
    }

    private static void changeLogger(String bindLoggerName, String loggerName, String level) {
        String lname = logger.getClass().getName().toLowerCase();
        if (lname.contains(BindLoger.logback.name())) {
            LogbackModifier.modifyLoggerLevel(loggerName, level);
        } else if (lname.contains(BindLoger.log4j.name())) {
            Log4jModifier.modifyLoggerLevel(loggerName, level);
        }
    }
    // private static void changeLogger(String bindLoggerName,String loggerName,String level) {
    // bindLoggerName = bindLoggerName.toLowerCase();
    // LogLevelConfig logLevelConfig = logLevelConfigMap.get(bindLoggerName);
    // if(null != logLevelConfig ){
    // Logger logger = LoggerFactory.getLogger(loggerName);
    // try {
    // Class<?> levelClass = Class.forName(logLevelConfig.getLevelClass());
    // Class<?> loggerClass = Class.forName(logLevelConfig.getLoggerClass());
    // Method toLevel = ReflectionUtils.findMethod(levelClass, "toLevel", String.class);
    // Method setLevel = ReflectionUtils.findMethod(loggerClass, "setLevel", levelClass);
    // Object levelValue = ReflectionUtils.invokeMethod(toLevel, null, level);
    // ReflectionUtils.invokeMethod(setLevel, logger, levelValue);
    // } catch (Exception e) {
    // logger.error("change logger level exception: {}",e.getMessage());
    // }
    // }
    // }
}
